//
//  TransferprotocolHelp2.swift
//  CarNotify
//
//  Created by 方强 on 16/2/18.
//  Copyright © 2016年 MT. All rights reserved.
//

import Foundation

public class TransferprotocolHelp {
    private static let START_BYTE:UInt8 = 0xAA;
    private static let MID_BYTE:UInt8   = 0xA5;
    private static let END_BYTE:UInt8   = 0x55;
    
    private var revice_buffer_start:Int = 0;
    private var recive_buffer_end:Int   = 0;
    private static let BUFFER_SIZE:Int = 1024;
    private var recive_buffer:Data = Data(bytes: [UInt8](repeating: 0, count: TransferprotocolHelp.BUFFER_SIZE));
    
    private var callback:TransferprotocolHelp.Callback?;
    // 设置回调方法
    public func setCallback(callback:TransferprotocolHelp.Callback?){
        self.callback = callback;
    }
    
    // 获取数据并且储存
    public func putDatas(datas:Data?){
        if((datas == nil) || (datas?.count == 0)){
            return;
        }
        
        for b in datas!{
            putByte(data: b);
        }
    }
    
    // 获取一个字节数据
    private var hasmid = false;
    private var hasstart = false;
    private func putByte(data:UInt8){
        if (hasmid) {
            recive_buffer[recive_buffer_end] = data;
            recive_buffer_end = (recive_buffer_end + 1) % recive_buffer.count;
            hasmid = false;
        } else {
            if (data == TransferprotocolHelp.START_BYTE) { // 遇到起始位置
                hasstart = true;
                recive_buffer_end = 0;
                return;
            }
            
            if (!hasstart) { // 如果没有遇到起始位置，就直接丢弃
                return;
            }
            
            if (data == TransferprotocolHelp.MID_BYTE) { // 遇到转义
                hasmid = true;
                return;
            }
            
            if (data == TransferprotocolHelp.END_BYTE) { // 遇到结束，进行回调反馈
                hasstart = false;
                hasmid = false;
                var full_byte = Data(bytes: [UInt8](repeating: 0, count: recive_buffer_end));
                for i in 0 ..< recive_buffer_end{
                    full_byte[i] = recive_buffer[i];
                }
                
                callback?.onGetcmd?(full_byte);
                return;
            }
            recive_buffer[recive_buffer_end] = data; // 直接进行存储
            recive_buffer_end = (recive_buffer_end + 1) % recive_buffer.count;
        }
    }
    
    // 将数据打包成发送的格式
    public class func packgeDatas(datas:[UInt8]?) -> [UInt8]?{
        
        if ((datas == nil) || (datas!.count < 1)) {
            return nil;
        }
        var lenght = 0;
        for i in 0 ..< datas!.count{
            if ((START_BYTE == datas![i]) || (MID_BYTE == datas![i])
                || (END_BYTE == datas![i])) {
                    lenght += 1;
            }
        }
        
        lenght += (datas?.count)!;
        lenght += 2; // 添加起始位和结束位
        
        var data = [UInt8](repeating: 0, count: lenght);
        
        var j = 0;
        data[j] = START_BYTE;
        j += 1;
        for i in 0 ..< datas!.count{
            if ((START_BYTE == datas![i]) || (MID_BYTE == datas![i])
                || (END_BYTE == datas![i])) {
                    data[j] = MID_BYTE; // 添加转义
                j += 1;
            }
            data[j] = datas![i];
            j += 1;
        }
        data[j] = END_BYTE;
        j += 1;
        
        return data;
    }
    
    // 检查校验
    public class func checkErro(datas:Data?) -> Bool{
        
        if (datas == nil) {
            return false;
        }
        
        var lrc:UInt8 = 0;
        for i in 0 ..< datas!.count { // 计算校验
            lrc = lrc &+ datas![i];
        }
        
        if (lrc == 0) { // 校验没问题
            return true;
        }
        
        return false;
    }
    
    // 获取校验值
    public class func getLRCCheckByte(datas:[UInt8]?, lenght:Int) -> UInt8? {
        
        if(datas == nil){
            return nil;
        }
        
        var lrc:UInt8 = 0;
        var lenght_tmp = lenght;
        if(lenght > datas!.count){
            lenght_tmp = (datas?.count)!;
        }
        for i in 0 ..< lenght_tmp{
            lrc = lrc &+ datas![i];
        }
        lrc = 0 &- lrc;
        
        return lrc;
    }
    
    public class Callback{
        var onGetcmd:((Data)->Void)?;
    }
    
}
